/*
 *  Copyright 2008 Mark Ashworth <javameme@gmail.com>.
 * 
 *  Licensed under the GNU General Public License v3 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.gnu.org/licenses/gpl-3.0.html
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package xperiment.metaphor.model.system;

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import xperiment.metaphor.model.DomainObject;
import xperiment.metaphor.model.Persistent;

/**
 * Message
 * 
 * @author Mark Ashworth <javameme@gmail.com>
 * @version 1.0.0
 * @since 1.0.0
 */
public class Message extends DomainObject implements Persistent {
    private static final long serialVersionUID = 1L;
    
    public static final Message EMPTY = new Message();   
    
    /* The unique database id for the object */
    private Long id = null;
    
    /*
     * The type of message. Message types are uppercased values like, 
     * ALERT, ERROR, NOTIFICATION, INFO, QUESTION, TASK, NOTE and it is upto the
     * client application to process the different message types.
     */
    private String type;

    /* Action that triggered the message */
    private String action;

    /* Body of the message */
    private String body;

    /* Application specific details */
    private String details;

    /* The sender of the message */
    private Long senderId;
    
    /* The recipient of the message */
    private Long recipientId;
    
    /* The date the message was sent */
    private Date sent;
    
    /* The date the message was received */
    private Date received;
    
    /* The date the message was read */
    private Date read;

    /* Whether the message is enabled */
    private boolean enabled = true;
    
    /**
     * Default constructor
     */
    public Message() {
        super();
    }

    /**
     * Constructs the message
     * @param senderId The sender of the message
     * @param recipientId The recipient of the message
     * @param body The body of the message
     */
    public Message(Long senderId, Long recipientId, String body) {
        super();
        setSenderId(senderId);
        setRecipientId(recipientId);
        setBody(body);
    }
    
    /**
     * The unique database id for the object
     * @return Long
     */
	public Long getId() {
		return id;
	}

    /**
     * The type of message. Message types are uppercased values like, 
     * ALERT, ERROR, NOTIFICATION, INFO, QUESTION, TASK, NOTE and it is upto the
     * client application to process the different message types.
     * @return String
     */
    public String getType() {
        return type;
    }

    /**
     * The type of message. Message types are uppercased values like, 
     * ALERT, ERROR, NOTIFICATION, INFO, QUESTION, TASK, NOTE and it is upto the
     * client application to process the different message types.
     * @param type The new value
     */
    public void setType(String type) {
        String old = getType();
        this.type = (type == null ? null : type.toUpperCase());
        firePropertyChange("type", old, getType());
    }
    
    /**
     * An URL or someother application specific action that the user is required
     * to perform. For example, if the message originated from the security
     * module because a user has attempted to log on but failed to do so for
     * three attempts then the action to the administrator might be to 
     * investigate if the account is locked by visiting /app/admin/user?id=23.
     * 
     * @return String
     */
    public String getAction() {
        return action;
    }

    /**
     * An URL or someother application specific action that the user is required
     * to perform. For example, if the message originated from the security
     * module because a user has attempted to log on but failed to do so for
     * three attempts then the action to the administrator might be to 
     * investigate if the account is locked by visiting /app/admin/user?id=23.
     * @param action The new value
     */
    public void setAction(String action) {
        String old = getAction();
        this.action = action;
        firePropertyChange("action", old, getAction());
    }

    /**
     * The body of the message
     * @return String
     */
    public String getBody() {
        return body;
    }

    /**
     * The body of the message
     * @param body The new value
     */
    public void setBody(String body) {
        String old = getBody();
        this.body = body;
        firePropertyChange("body", old, getBody());
    }

    /**
     * Returns a portion of the body message upto length number of characters
     * @param length The number of characters to return
     * @return The snippet
     */
    @Transient
    public String getBodySnippet(int length) {
        if (getBody() != null) {
            getBody().substring(0, length);
        }
        return getBody();
    }
    
    /**
     * Application specific details relating to the message. This could be an 
     * XML document, or a serializable object or a comma-separated value string.
     * @return String
     */
    public String getDetails() {
        return details;
    }

    /**
     * Application specific details relating to the message. This could be an 
     * XML document, or a serializable object or a comma-separated value string.
     * @param details The new value
     */
    public void setDetails(String details) {
        String old = getDetails();
        this.details = details;
        firePropertyChange("details", old, getDetails());
    }

    /**
     * The date the message was read by the recipient.
     * @return Date
     */
    public Date getRead() {
        return read;
    }

    /**
     * The date the message was read by the recipient.
     * @param read The new value
     */
    public void setRead(Date read) {
        Date old = getRead();
        this.read = read;
        firePropertyChange("read", old, getRead());
    }

    /**
     * The date the message was received by the recipient. This value might be 
     * null in environments where the sent date and the received dates are
     * processed by the same system.
     * @return Date
     */
    public Date getReceived() {
        return received;
    }

    /**
     * The date the message was received by the recipient. This value might be 
     * null in environments where the sent date and the received dates are
     * processed by the same system.
     * @param received The new value
     */
    public void setReceived(Date received) {
        Date old = getReceived();
        this.received = received;
        firePropertyChange("received", old, getReceived());
    }

    /**
     * The recipient of the message. This value is required.
     * @return Long
     */
    public Long getRecipientId() {
        return recipientId;
    }

    /**
     * The recipient of the message. This value is required.
     * @param recipientId The new value
     */
    public void setRecipientId(Long recipientId) {
        Long old = getRecipientId();
        this.recipientId = recipientId;
        firePropertyChange("recipientId", old, getRecipientId());
    }

    /**
     * The sender of the message. This value is required.
     * @return Long
     */
    public Long getSenderId() {
        return senderId;
    }

    /**
     * The sender of the message. This value is required.
     * @param senderId The new value
     */
    public void setSenderId(Long senderId) {
        Long old = getSenderId();
        this.senderId = senderId;
        firePropertyChange("senderId", old, getSenderId());
    }

    /**
     * The date that the message was sent
     * @return Date
     */
    public Date getSent() {
        return sent;
    }

    /**
     * The date that the message was sent
     * @param sent The new value
     */
    public void setSent(Date sent) {
        Date old = getSent();
        this.sent = sent;
        firePropertyChange("sent", old, getSent());
    }
    
    public boolean isEnabled() {
        return this.enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}
